/**
 * @file Bsp_Bq4050.c
 * @author 徐松亮 (5387603@qq.com)
 * @version 1.0
 * @date 2023-09-27
 *
 * @copyright Copyright (c) {2030}  沈阳迈思医疗科技有限公司
 *
 * @brief 驱动层-->锂电池充电管理芯片BQ4050驱动程序
 */
/* 私有头部文件 (Includes)-----------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "Bsp_Bq4050.h"
/* 编译警告条件 (Compile warning condition)------------------------------------*/
#if (defined(PROJECT_TEST_BSP_BQ4050))
#warning Please Set Effective Project to Bsp_Bq4050.h
#endif
/* 私有类型定义 (Private typedef)----------------------------------------------*/
/* 私有型宏定义 (Private define)-----------------------------------------------*/
#define BSP_BQ4050_MANUFACTURER_CMD_R_DEVICE_TYPE 0x0001
#define BSP_BQ4050_MANUFACTURER_CMD_R_FIRMWARE_VERSION 0x0002
#define BSP_BQ4050_MANUFACTURER_CMD_R_HARDWARE_VERSION 0x0003
#define BSP_BQ4050_MANUFACTURER_CMD_R_IF_CHECK_SUM 0x0004
#define BSP_BQ4050_MANUFACTURER_CMD_R_STATIC_DF_SIGNATURE 0x0005
#define BSP_BQ4050_MANUFACTURER_CMD_R_AII_DF_SIGNATURE 0x0009
#define BSP_BQ4050_MANUFACTURER_CMD_W_SHUTDOWN_MODE 0x0010
#define BSP_BQ4050_MANUFACTURER_CMD_W_SLEEP_MODE 0x0011
#define BSP_BQ4050_MANUFACTURER_CMD_W_FUSE_TOGGLE 0x001D
#define BSP_BQ4050_MANUFACTURER_CMD_W_PRECHARGE_FET 0x001E
#define BSP_BQ4050_MANUFACTURER_CMD_W_CHARGE_FET 0x001F
#define BSP_BQ4050_MANUFACTURER_CMD_W_DISCHARGE_FET 0x0020
#define BSP_BQ4050_MANUFACTURER_CMD_W_FET_CONTROL 0x0022
#define BSP_BQ4050_MANUFACTURER_CMD_W_LIFETIME_DATA_COLLECTION 0x0023
#define BSP_BQ4050_MANUFACTURER_CMD_W_PERMANENT_FAILURE 0x0024
#define BSP_BQ4050_MANUFACTURER_CMD_W_BLACK_BOX_RECORDER 0x0025
#define BSP_BQ4050_MANUFACTURER_CMD_W_FUSE 0x0026
#define BSP_BQ4050_MANUFACTURER_CMD_W_LIFETIME_DATA_RESET 0x0028
#define BSP_BQ4050_MANUFACTURER_CMD_W_PERMANENT_FAILURE_DATA_RESET 0x0029
#define BSP_BQ4050_MANUFACTURER_CMD_W_LIFETIME_DATA_FLUSH 0x002E
#define BSP_BQ4050_MANUFACTURER_CMD_W_LIFETIME_DATA_SPEED_UP_MODE 0x002F
#define BSP_BQ4050_MANUFACTURER_CMD_W_BLACK_BOX_RECORDER_RESET 0x002A
#define BSP_BQ4050_MANUFACTURER_CMD_W_CALIBRATION_MODE 0x002D
#define BSP_BQ4050_MANUFACTURER_CMD_W_SEAL_DEVICE 0x0030
#define BSP_BQ4050_MANUFACTURER_CMD_RW_SECURITY_KEYS 0x0035
#define BSP_BQ4050_MANUFACTURER_CMD_RW_AUTHENTICATION_KEY 0x0037
#define BSP_BQ4050_MANUFACTURER_CMD_W_DEVICE_RESET 0x0041
#define BSP_BQ4050_MANUFACTURER_CMD_R_SAFETY_ALERT 0x0050
#define BSP_BQ4050_MANUFACTURER_CMD_R_SAFETY_STATUS 0x0051
#define BSP_BQ4050_MANUFACTURER_CMD_R_PF_ALERT 0x0052
#define BSP_BQ4050_MANUFACTURER_CMD_R_PF_STATUS 0x0053
#define BSP_BQ4050_MANUFACTURER_CMD_R_OPERATION_STATUS 0x0054
#define BSP_BQ4050_MANUFACTURER_CMD_R_CHARGING_STATUS 0x0055
#define BSP_BQ4050_MANUFACTURER_CMD_R_GAUGING_STATUS 0x0056
#define BSP_BQ4050_MANUFACTURER_CMD_R_MANUFACTURING_STATUS 0x0057
#define BSP_BQ4050_MANUFACTURER_CMD_R_AFE_REGISTER 0x0058
#define BSP_BQ4050_MANUFACTURER_CMD_R_LIFETIME_DATA_BLOCK1 0x0060
#define BSP_BQ4050_MANUFACTURER_CMD_R_LIFETIME_DATA_BLOCK2 0x0061
#define BSP_BQ4050_MANUFACTURER_CMD_R_LIFETIME_DATA_BLOCK3 0x0062
#define BSP_BQ4050_MANUFACTURER_CMD_R_MANUFACTURER_INFO 0x0070
#define BSP_BQ4050_MANUFACTURER_CMD_R_DA_STATUS1 0x0071
#define BSP_BQ4050_MANUFACTURER_CMD_R_DA_STATUS2 0x0072
#define BSP_BQ4050_MANUFACTURER_CMD_R_MANUFACTURER_INFOB 0x007A
#define BSP_BQ4050_MANUFACTURER_CMD_W_ROM_MODE 0x0F00
#define BSP_BQ4050_MANUFACTURER_CMD_RW_EXIT_CALIBRATION_OUTPUT 0xF080
#define BSP_BQ4050_MANUFACTURER_CMD_RW_OUTPUT_CC_AND_ADC_FOR_CALIBRATION 0xF081
#define BSP_BQ4050_MANUFACTURER_CMD_RW_OUTPUT_SHORTED_CC_AND_ADC_FOR_CALIBRATION 0xF082

#define BSP_BQ4050_CMD_RW_REMAINING_CAPACITY_ALARM 0x01
#define BSP_BQ4050_CMD_RW_REMAINING_TIME_ALARM 0x02
#define BSP_BQ4050_CMD_RW_BATTERY_MODE 0x03
#define BSP_BQ4050_CMD_RW_AT_RATE 0x04
#define BSP_BQ4050_CMD_R_AT_RATE_TIME_TO_FULL 0x05
#define BSP_BQ4050_CMD_R_AT_RATE_TIME_TO_EMPTY 0x06
#define BSP_BQ4050_CMD_R_AT_RATE_OK 0x07
#define BSP_BQ4050_CMD_R_TEMPERATURE 0x08
#define BSP_BQ4050_CMD_R_VOLTAGE_CELL 0x09
#define BSP_BQ4050_CMD_R_CURRENT_CHARGE 0x0A
#define BSP_BQ4050_CMD_R_AVERAGE_CURRENT_CHARGE 0x0B
#define BSP_BQ4050_CMD_R_MAX_ERROR 0x0C
#define BSP_BQ4050_CMD_R_RELATIVE_STATE_OF_CHARGE 0x0D
#define BSP_BQ4050_CMD_R_ABSOLUTE_STATE_OF_CHARGE 0x0E
#define BSP_BQ4050_CMD_R_REMAINING_CAPACITY 0x0F
#define BSP_BQ4050_CMD_R_FULL_CHARGE_CAPACITY 0x10
#define BSP_BQ4050_CMD_R_RUN_TIME_TO_EMPTY 0x11
#define BSP_BQ4050_CMD_R_AVERAGE_TIME_TO_EMPTY 0x12
#define BSP_BQ4050_CMD_R_AVERAGE_TIME_TO_FULL 0x13
#define BSP_BQ4050_CMD_R_CHARGING_CURRENT 0x14
#define BSP_BQ4050_CMD_R_CHARGING_VOLTAGE 0x15
#define BSP_BQ4050_CMD_R_BATTERY_STATUS 0x16
#define BSP_BQ4050_CMD_R_CYCLE_COUNT 0x17
#define BSP_BQ4050_CMD_R_DESIGN_CAPACITY 0x18
#define BSP_BQ4050_CMD_R_DESIGN_VOLTAGE 0x19
#define BSP_BQ4050_CMD_R_SPECIFICATION_INFO 0x1A
#define BSP_BQ4050_CMD_R_MANUFACTURER_DATE 0x1B
#define BSP_BQ4050_CMD_R_SERIAL_NUMBER 0x1C
#define BSP_BQ4050_CMD_R_MANUFACTURER_NAME 0x20
#define BSP_BQ4050_CMD_R_DEVICE_NAME 0x21
#define BSP_BQ4050_CMD_R_DEVICE_CHEMISTRY 0x22
#define BSP_BQ4050_CMD_R_MANUFACTURER_DATA 0x23
#define BSP_BQ4050_CMD_RW_AUTHENTICATE 0x2F
#define BSP_BQ4050_CMD_R_CELL_VOLTAGE4 0x3C
#define BSP_BQ4050_CMD_R_CELL_VOLTAGE3 0x3D
#define BSP_BQ4050_CMD_R_CELL_VOLTAGE2 0x3E
#define BSP_BQ4050_CMD_R_CELL_VOLTAGE1 0x3F
#define BSP_BQ4050_CMD_RW_BTP_DISCHARGE_SET 0x4A
#define BSP_BQ4050_CMD_RW_BTP_CHARGE_SET 0x4B
#define BSP_BQ4050_CMD_N_STATE_OF_HEALTH 0x4F
#define BSP_BQ4050_CMD_N_SAFETY_ALERT 0x50
#define BSP_BQ4050_CMD_N_SAFETY_STATUS 0x51
#define BSP_BQ4050_CMD_N_PF_ALERT 0x52
#define BSP_BQ4050_CMD_N_PF_STATUS 0x53
#define BSP_BQ4050_CMD_N_OPERATION_STATUS 0x54
#define BSP_BQ4050_CMD_N_CHARGING_STATUS 0x55
#define BSP_BQ4050_CMD_N_GAUGING_STATUS 0x56
#define BSP_BQ4050_CMD_N_MANUFACTURING_STATUS 0x57
#define BSP_BQ4050_CMD_N_REGISTER 0x58
#define BSP_BQ4050_CMD_N_LIFETIME_DATA_BLOCK_1 0x60
#define BSP_BQ4050_CMD_N_LIFETIME_DATA_BLOCK_2 0x61
#define BSP_BQ4050_CMD_N_LIFETIME_DATA_BLOCK_3 0x62
#define BSP_BQ4050_CMD_N_LIFETIME_DATA_BLOCK_4 0x63
#define BSP_BQ4050_CMD_N_LIFETIME_DATA_BLOCK_5 0x64
#define BSP_BQ4050_CMD_R_MANUFACTURER_INFO 0x70
#define BSP_BQ4050_CMD_N_DA_STATUS1 0x71
#define BSP_BQ4050_CMD_N_DA_STATUS2 0x72

/* 私有变量定义 (Private variables)--------------------------------------------*/
/* 私有函数声明 (Private function prototypes)----------------------------------*/
static uint8_t Bsp_Bq4050_ReadReg(BSP_BQ4050_T_INTERFACE *_tp_interface, uint8_t cmd, uint8_t *pbuf);
static void BspBq4050_Cycle_1000ms(void *_tp_interface);
/* 私有函数实体 (Private functions)--------------------------------------------*/
static uint8_t Bsp_Bq4050_ReadReg(BSP_BQ4050_T_INTERFACE *_tp_interface, uint8_t cmd, uint8_t *pbuf)
{
    uint8_t res = false;
    // 开始
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_Start(_tp_interface->t_Input.tp_GpioIIC);
    // 器件地址+写
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_SendByte(_tp_interface->t_Input.tp_GpioIIC, BSP_BQ4050_IIC_ADDR | BSP_GPIO_IIC_WR);
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
    if (_tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_WaitAck(_tp_interface->t_Input.tp_GpioIIC) != 0)
    {
        res = true;
        goto goto_Bsp_Bq4050_ReadReg;
    }
    // 命令
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_SendByte(_tp_interface->t_Input.tp_GpioIIC, cmd);
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
    if (_tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_WaitAck(_tp_interface->t_Input.tp_GpioIIC) != 0)
    {
        res = true;
        goto goto_Bsp_Bq4050_ReadReg;
    }
    // 开始
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_Start(_tp_interface->t_Input.tp_GpioIIC);
    // 器件地址+读
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_SendByte(_tp_interface->t_Input.tp_GpioIIC, BSP_BQ4050_IIC_ADDR | BSP_GPIO_IIC_RD);
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
    if (_tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_WaitAck(_tp_interface->t_Input.tp_GpioIIC) != 0)
    {
        res = true;
        goto goto_Bsp_Bq4050_ReadReg;
    }
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
    // 读数据
    pbuf[0] = _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_ReadByte(_tp_interface->t_Input.tp_GpioIIC);
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_Ack(_tp_interface->t_Input.tp_GpioIIC);
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
    pbuf[1] = _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_ReadByte(_tp_interface->t_Input.tp_GpioIIC);
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_NAck(_tp_interface->t_Input.tp_GpioIIC);
    _tp_interface->t_Input.fnp_OsDelay_ms(1);
goto_Bsp_Bq4050_ReadReg:
    _tp_interface->t_Input.tp_GpioIIC->t_Output.fnp_IIC_Stop(_tp_interface->t_Input.tp_GpioIIC);
    return res;
}

/**
 * @brief   周期执行函数
 * @note    用于Debug测试等
 * @param   None
 * @return  None
 */
static void BspBq4050_Cycle_1000ms(void *_tp_interface)
{
    BSP_BQ4050_T_INTERFACE *tp_interface = _tp_interface;
    {
        // 5小时周期，充电复位
        {
            tp_interface->t_Private.us_VccResetTimer_s++;
            if (tp_interface->t_Private.us_VccResetTimer_s == (3600 * 5))
            {
                tp_interface->t_Private.us_VccResetTimer_s = 0;
                tp_interface->t_Private.uc_VccResetStep = 1;
            }
        }
        // 连续4分钟不充电，充电复位
        {
            if ((0 <= tp_interface->t_Output.s_CellCurrent_mA) &&
                (tp_interface->t_Output.s_CellCurrent_mA <= 100) &&
                (tp_interface->t_Output.us_CellVoltage_mV <= 16500))
            {
                tp_interface->t_Private.uc_VccResetConditionTimer_s++;
            }
            else
            {
                tp_interface->t_Private.uc_VccResetConditionTimer_s = 0;
            }
            if (tp_interface->t_Private.uc_VccResetConditionTimer_s > 240)
            {
                tp_interface->t_Private.uc_VccResetConditionTimer_s = 0;
                tp_interface->t_Private.uc_VccResetStep = 1;
            }
        }
        // 充电复位使能标识处理
        switch (tp_interface->t_Private.uc_VccResetStep)
        {
        case 1:
            tp_interface->t_Input.fnp_WriteGpioPower(false);
            tp_interface->t_Private.uc_VccResetStep++;
            break;
        default:
            tp_interface->t_Input.fnp_WriteGpioPower(true);
            break;
        }
    }
    //
    switch (tp_interface->t_Private.uc_CycleStep)
    {
        // 单次
    case 0:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_DESIGN_CAPACITY, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_DesignCapacity = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
            tp_interface->t_Private.uc_CycleStep++;
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 1:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_DESIGN_VOLTAGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_DesignVoltage = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
            tp_interface->t_Private.uc_CycleStep++;
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 2:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_SERIAL_NUMBER, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_SerialNumber = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
            tp_interface->t_Private.uc_CycleStep++;
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 3:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_CYCLE_COUNT, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_CycleCount = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
            tp_interface->t_Private.uc_CycleStep++;
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 4:
        tp_interface->t_Private.uc_CycleStep++;
        break;
    case 5:
        tp_interface->t_Private.uc_CycleStep++;
        break;
    case 6:
        tp_interface->t_Private.uc_CycleStep++;
        break;
    case 7:
        tp_interface->t_Private.uc_CycleStep++;
        break;
    case 8:
        tp_interface->t_Private.uc_CycleStep++;
        break;
    case 9:
        tp_interface->t_Private.uc_CycleStep++;
        break;
        // 循环
    case 10:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_TEMPERATURE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.c_Temp = (MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]) / 10) - 273;
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 11:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_VOLTAGE_CELL, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_CellVoltage_mV = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 12:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_CURRENT_CHARGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.s_CellCurrent_mA = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 13:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_AVERAGE_CURRENT_CHARGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.s_CellAverageCurrent_mA = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 14:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_RELATIVE_STATE_OF_CHARGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.uc_RelativeStateOfCharge = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 15:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_ABSOLUTE_STATE_OF_CHARGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.uc_AbsoluteStateOfCharge = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 16:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_REMAINING_CAPACITY, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.us_RemainingCapacity_mAh = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 17:
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_BATTERY_STATUS, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Private.uc_CycleStep++;
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->t_Output.u_BatteryStatus.us_BatteryStatus = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
        /*
    case 17:
        tp_interface->t_Private.uc_CycleStep++;
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_CHARGING_CURRENT, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->ChargingCurrent_mA = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
    case 18:
        tp_interface->t_Private.uc_CycleStep++;
        if (false == Bsp_Bq4050_ReadReg(tp_interface, BSP_BQ4050_CMD_R_CHARGING_VOLTAGE, tp_interface->t_Private.uca_buf))
        {
            tp_interface->t_Output.uc_Communication_State = false;
            tp_interface->t_Output.ul_Communication_Cmt_OK++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 0;
            tp_interface->ChargingVoltage_mV = MODULE_COUNT_2ByteToWord(tp_interface->t_Private.uca_buf[1], tp_interface->t_Private.uca_buf[0]);
        }
        else
        {
            tp_interface->t_Output.ul_Communication_Cmt_ERROR++;
            tp_interface->t_Output.uc_Communication_Cmt_ContinueErr++;
        }
        break;
        */
    default:
        tp_interface->t_Private.uc_CycleStep = 10;
        break;
    }
    // 状态错误判定(连续60次通讯失败，则判定故障)
    if (tp_interface->t_Output.uc_Communication_Cmt_ContinueErr > 30)
    {
        tp_interface->t_Output.uc_Communication_Cmt_ContinueErr = 30;
        tp_interface->t_Output.uc_Communication_State = true;
    }
    // Debug
    {
        if (tp_interface->t_Private.uc_DebugTestEnable == 1)
        {
            int8_t *pbuf;
            pbuf = ModuleMemManager_Get(E_MEM_MANAGER_TYPE_256B);
            sprintf((char *)pbuf, "----------BQ4050----------\r\n");
            tp_interface->t_Input.fnp_DebugOutStr(pbuf);
            if (tp_interface->t_Private.uc_DebugFirst == 0)
            {
                tp_interface->t_Private.uc_DebugFirst = 1;
                sprintf((char *)pbuf, "%-25s%u\r\n", "DesignCapacity", tp_interface->t_Output.us_DesignCapacity);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "DesignVoltage", tp_interface->t_Output.us_DesignVoltage);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "SerialNumber", tp_interface->t_Output.us_SerialNumber);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "CycleCount", tp_interface->t_Output.us_CycleCount);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
            }
            else
            {
                // 循环读取
                sprintf((char *)pbuf, "%-25s%u\r\n", "Communication_Cmt_OK", tp_interface->t_Output.ul_Communication_Cmt_OK);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "Communication_Cmt_ERROR", tp_interface->t_Output.ul_Communication_Cmt_ERROR);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%d\r\n", "Temp", tp_interface->t_Output.c_Temp);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "CellVoltage_mV", tp_interface->t_Output.us_CellVoltage_mV);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%d\r\n", "CellCurrent_mA", tp_interface->t_Output.s_CellCurrent_mA);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%d\r\n", "CellAverageCurrent_mA", tp_interface->t_Output.s_CellAverageCurrent_mA);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "RelativeStateOfCharge", tp_interface->t_Output.uc_RelativeStateOfCharge);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "AbsoluteStateOfCharge", tp_interface->t_Output.uc_AbsoluteStateOfCharge);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
                sprintf((char *)pbuf, "%-25s%u\r\n", "RemainingCapacity_mAh", tp_interface->t_Output.us_RemainingCapacity_mAh);
                tp_interface->t_Input.fnp_DebugOutStr(pbuf);
            }
            ModuleMemManager_Free(E_MEM_MANAGER_TYPE_256B, pbuf);
        }
        else
        {
            tp_interface->t_Private.uc_DebugFirst = 0;
        }
    }
}
/* 公有函数实体 (Public functions)---------------------------------------------*/
/**
 * @brief   初始化函数
 * @note    用于初始化变量
 * @param   None
 * @return  None
 */
void BspBq4050_Init(BSP_BQ4050_T_INTERFACE *_tp_interface)
{
    _tp_interface->t_Transplant.fnp_Cycle_1000ms = BspBq4050_Cycle_1000ms;
}
/**
 * @brief   Debug接口函数
 * @note    开启Debug相关指令后会循环打印
 * @param   OnOff-判断指令进入与退出
 * @return  None
 */
void BspBq4050_DebugTestOnOff(uint8_t _uc_trueOrFalse, void *_tp_interface)
{
    BSP_BQ4050_T_INTERFACE *tp_interface = _tp_interface;
    if (tp_interface == NULL)
    {
        return;
    }
    if (_uc_trueOrFalse == true)
    {
        tp_interface->t_Private.uc_DebugTestEnable = 1;
    }
    else
    {
        tp_interface->t_Private.uc_DebugTestEnable = 0;
    }
}
/******************* (C) COPYRIGHT 2030 XSLXHN *****END OF FILE****************/
